#include "CdiRenderBox.h"
#include "CdiRenderObjectList.h"
#include "vertextypes.h"

CdiRenderBox::CdiRenderBox(LPDIRECT3DDEVICE9 pDevice, float scale ) : CdiBox( pDevice, scale )
{
  Setup();
}

CdiRenderBox::~CdiRenderBox(void)
{
  if( m_vertexBuffer )
  {
    m_vertexBuffer->Release();
  }

  if( m_pIndexBuffer )
  {
    m_pIndexBuffer->Release();
  }

  if( m_objectList )
  {
    delete m_objectList;
  }
  m_objectList = NULL;
  m_pIndexBuffer = NULL;
  m_vertexBuffer = NULL;
}

HRESULT CdiRenderBox::Attach( CdiBox& box )
{
  AssertValid();
  bool added = m_objectList->AddObject( (CdiRenderBase*)&box );
  if( added )
    return S_OK;
  return E_FAIL;
}

BOOL CdiRenderBox::SetRender( BOOL renderState )
{
  m_enabled = renderState;
  return m_enabled;
}

HRESULT CdiRenderBox::Render( LPDIRECT3DDEVICE9 pDevice )
{
  AssertValid();
  if( pDevice == NULL )
  {
    pDevice = m_pDevice;
  }
  BOOL rendered = FALSE;
  HRESULT hr = pDevice->SetStreamSource( 0, m_vertexBuffer, 0, sizeof( ColorVertex ) );
  if( SUCCEEDED( hr ) )
  {
    hr = pDevice->SetIndices( m_pIndexBuffer );
    if( SUCCEEDED( hr ) )
    {
      hr = pDevice->SetFVF( FVFXYZ_COLOR );
      if( SUCCEEDED( hr ) )
      {    
        hr = pDevice->DrawIndexedPrimitive( m_primitiveType, 0, 0, 36, 0, 12 ); 
        if( SUCCEEDED( hr ) ) 
        {
          if( m_objectList != NULL )
          {
            m_objectList->RenderAll( pDevice );
          }
          rendered = TRUE;
        }
      }
    }
  }
  if( FALSE == rendered )
  {
    SetRender( FALSE );
  }
  return (rendered == TRUE?S_OK:E_FAIL);
}

BOOL CdiRenderBox::CanRender() const
{
  return m_enabled;
}

void CdiRenderBox::Setup()
{
  AssertValid();
  m_primitiveType = D3DPT_TRIANGLELIST;
  m_objectList = new CdiRenderObjectList();
  SetRender( FALSE );

  HRESULT hr = CreateVertexBuffer();

  if( SUCCEEDED( hr ) )
  {
    SetRender( TRUE );
  }
}

HRESULT CdiRenderBox::CreateVertexBuffer()
{
  AssertValid();

    /*
          4.___7.
  0.___3. |     |
   |    | 5.___6.
  1.___2.

  */

  short indices[36] = { 0,3,1,//
                        3,2,1,//* Front
                        
                        3,7,2,//
                        7,6,2,//* Top

                        4,0,1,//
                        1,5,4,//* Back

                        0,4,3,//
                        4,7,3,//* right side

                        1,2,5,//
                        2,6,5,//* left side

                        5,6,4,//                                                                                                              
                        6,7,4,//* back side
                      };

  // BUGBUG: 5/26/07: Setting up the index buffer causes a first chance exception
  HRESULT hr = m_pDevice->CreateIndexBuffer(  sizeof( short ) * 36, 
                                              D3DUSAGE_WRITEONLY, 
                                              D3DFMT_INDEX16, 
                                              D3DPOOL_MANAGED, 
                                              &m_pIndexBuffer, 
                                              NULL );

  if( SUCCEEDED( hr ) && m_pIndexBuffer != NULL ) 
  {
    BYTE* pIndexData = NULL;
    hr = m_pIndexBuffer->Lock(0, 0, (void**)&pIndexData, 0 );
    if( SUCCEEDED( hr ) ) 
    {
      CopyMemory( pIndexData, (void*)&indices, sizeof( indices ) );
      hr = m_pIndexBuffer->Unlock();
      if( SUCCEEDED (hr) )
      {
        hr = m_pDevice->CreateVertexBuffer( sizeof( ColorVertex )*8, 
                                            D3DUSAGE_WRITEONLY, 
                                            FVFXYZ_COLOR, 
                                            D3DPOOL_DEFAULT, 
                                            &m_vertexBuffer, 
                                            NULL );

        if( SUCCEEDED( hr ) && m_vertexBuffer != NULL)
        {
          BYTE* pVertData = 0;
          m_vertexBuffer->Lock( 0, sizeof( ColorVertex ), (void**)&pVertData, 0 );
          CopyMemory( pVertData, (void*)&m_simpleVertex, sizeof( m_simpleVertex ) * 36 );
          m_vertexBuffer->Unlock();
        }
      }
    }
  }
  return hr;
}

void CdiRenderBox::SetRenderType( D3DPRIMITIVETYPE primitiveType )
{
  m_primitiveType = primitiveType;
}
